import type { TagGroupProps} from "../TagGroup";
import TagGroup from "../TagGroup";
import Input from "../FormElements/Input";
import { computed, defineComponent, nextTick, PropType, ref, Ref, VNode, watchEffect } from "vue";
import { FeatherXCircle } from "cui-vue-icons/feather";

export interface ValueProps {
    prepend?: any
    text?: string | VNode | Array<any>
    clearable?: boolean
    icon?: VNode
    disabled?: boolean
    size?: 'small'|'large'
    multi?: boolean
    showMax?: TagGroupProps['max']
    onlyInput?: boolean
    placeholder?: string
    valueClosable?: boolean,
    filter?: boolean,
    query?: Ref<any>
    showMore?: boolean,
    tagRender?: (item: any) => string | number | VNode
}

export const Value = defineComponent({
    props: {
        prepend: {type: [String, Number, Object] as PropType<ValueProps['prepend']>},
        text: {type: [String, Object, Array] as PropType<ValueProps['text']>},
        clearable: {type: Boolean as PropType<ValueProps['clearable']>},
        icon: {type: Object as PropType<ValueProps['icon']>},
        disabled: {type: Boolean as PropType<ValueProps['disabled']>},
        size: {type: String as PropType<ValueProps['size']>},
        multi: {type: Boolean as PropType<ValueProps['multi']>},
        showMax: {type: [Number, String] as PropType<ValueProps['showMax']>},
        onlyInput: {type: Boolean as PropType<ValueProps['onlyInput']>},
        placeholder: {type: String as PropType<ValueProps['placeholder']>},
        valueClosable: {type: Boolean as PropType<ValueProps['valueClosable']>},
        filter: {type: Boolean as PropType<ValueProps['filter']>},
        query: {type: Object as PropType<ValueProps['query']>},
        showMore: {type: Boolean as PropType<ValueProps['showMore']>},
        tagRender: {type: Function as PropType<ValueProps['tagRender']>}
    },
    emits: ['clear', 'input', 'close', 'deleteLastValue'],
    setup (props: ValueProps, { slots, emit }) {
        const query = props.query ?? ref('');
        const filterStr = ref('');
        const filterInput = ref();
        const selection = ref();
        const onClear = (e: any) => {
            e.stopImmediatePropagation && e.stopImmediatePropagation();
            e.preventDefault && e.preventDefault();
            e.stopPropagation && e.stopPropagation();
            emit('clear', e);
        };
        const classList = () => ({
            'cm-field-value': true,
            'cm-field-clearable': props.clearable && !!props.text && !!props.text?.length,
            'cm-field-disabled': props.disabled,
            [`cm-field-value-${props.size}`]: !!props.size,
        });

        const multiText = computed(() => {
            nextTick(() => {
                if (props.filter && filterInput.value) {
                    const input = filterInput.value.getInput();
                    input.focus();
                }
            });
            if (props.multi && props.text && props.text instanceof Array) {
                return props.text.map((item: any, index: number) => {
                    return {id: item.id, title: props.tagRender?.(item) || item.title};
                });
            }
            return [];
        });

        const inputStyle = () => {
            // 查询内容变化时，更新输入框的宽度
            return {
                width: '10px',
                // width: str !== undefined ? str.length * 12 + 20 + 'px' : '100%',
            };
        };

        const updateFilterStyle = () => {
            if (!filterInput.value) {
                return;
            }
            const inputEl = filterInput.value.getInput();
            inputEl.style.width = '10px';
            inputEl.style.width = inputEl.scrollWidth + 'px';

            Promise.resolve().then(() => {
                inputEl.style.width = '10px';
                const maxWidth = Math.floor(selection.value?.getBoundingClientRect().width || 10);
                inputEl.style.width = inputEl.scrollWidth + 'px';
                inputEl.parentElement.style.width = Math.min(maxWidth-20, inputEl.scrollWidth) + 'px';
            });
        };

        watchEffect(() => {
            query.value;
            filterStr.value = query.value;
            updateFilterStyle();
        });

        // 因为Input输入中文时不会触发change事件，所以需要监听input事件进行更新
        const onFilterChange = (v: string, e: any) => {
            updateFilterStyle();
            filterStr.value = v;
        };

        const onValueClick = () => {
            if (props.filter && filterInput.value) {
                const input = filterInput.value.getInput();
                input.focus();
            }
        };

        const onFilterKeyDown = (e: any) => {
            const queryStr = query.value;
            if (e.key === 'Backspace' || e.code === 'Backspace'
            || e.key === 'Delete' || e.code === 'Delete') {
                if (queryStr.length === 0) {
                    emit('deleteLastValue');
                }
            }
        };

        const onFilterBlur = () => {
            if (props.onlyInput) {
                return;
            }
            if (props.filter) {
                filterStr.value = '';
                // setTimeout(() => {
                //     query.value = '';
                // }, 100);
            }
        };

        const onQueryChange = (v: string) => {
            query.value = v;
        };

        return () => <div class={classList()} tab-index="1" onClick={onValueClick}>
            <input type="hidden" />
            {/* 文字对齐辅助 */}
            <span style={{width: '0px', "font-size": '12px', visibility: 'hidden', 'line-height': 'initial'}}>A</span>
            {
                props.prepend ? <div class="cm-field-prepend">
                    {props.prepend}
                </div> : null
            }
            {
                props.multi ? <div class="cm-field-selection" ref={selection}>
                    <TagGroup data={multiText.value} closable={props.valueClosable} max={props.showMax} showMore={props.showMore} onClose={(...args) => emit('close', ...args)}
                        size={props.size === 'small' ? 'small' : 'large'} extra={
                            props.filter
                                ? <Input ref={filterInput} style={inputStyle()} class="cm-select-filter"
                                    trigger="input" size={props.size} v-model={filterStr.value} onChange={onQueryChange} onKeyDown={onFilterKeyDown} onInput={onFilterChange} onBlur={onFilterBlur}/>
                                : null
                        }/>
                </div>
                    : <div class="cm-field-text" ref={selection}>
                        {
                            !props.onlyInput
                                ? (props.text ? <span style={{display: filterStr.value ? 'none' : 'inline-block'}}>{props.text}</span> : <span class="cm-field-placeholder" style={{display: filterStr.value ? 'none' : 'inline-block'}}>{props.placeholder??''}</span>)
                                : null
                        }
                        {
                            props.filter
                                ? <Input ref={filterInput} style={inputStyle()} class="cm-select-filter"
                                    trigger="input" size={props.size} v-model={filterStr.value} onChange={onQueryChange} onInput={onFilterChange} onBlur={onFilterBlur}/>
                                : null
                        }
                    </div>
            }
            <span class="cm-field-cert">
                {props.icon}
            </span>
            {
                props.clearable && props.text && props.text !== ''
                    ? <FeatherXCircle class="cm-field-clear" onClick={onClear}/>
                    : null
            }
        </div>;
    }
});
